#pragma once
#ifndef __G_INSTANCE_ID_H__
#define __G_INSTANCE_ID_H__

#include "GCounter.h"
#include "GTypes.h"

namespace GUtil
{
	template <typename CountedType, typename U = GUInt32>
	class GInstanceId
	{
	typedef GAtomicCounter<U> CounterType;

	private:
		U InstanceId;

		static CounterType	NextId;
		static CounterType	InstanceCount;

	protected:
		GInstanceId()
		{
			InstanceId = NextId.Increment();
			InstanceCount.Increment();
		}
							
		GInstanceId(const GInstanceId<CountedType, U>& Other)
		{
			InstanceId = NextId.Increment();
			InstanceCount.Increment();
		}

		~GInstanceId()
		{
			InstanceCount.Decrement();
		}

	public:
		U GetInstanceId() const
		{
			return InstanceId;
		}

		static U GetInstanceCount()
		{
			return InstanceCount.GetCount();
		}
	
	}; // class GInstanceId

	template <typename CountedType, typename U>
	GAtomicCounter<U> GInstanceId<CountedType, U>::NextId;

	template <typename CountedType, typename U>
	GAtomicCounter<U> GInstanceId<CountedType, U>::InstanceCount;

}; // namespace GUtil
#endif